﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using BrightIdeasSoftware;
using System.Reflection;
using Managistics.Warehouse.Views.Libs.NNGrid.Controls;
using Managistics.Warehouse.Views.Libs.NNGrid.Datas;
using Managistics.Warehouse.Views.Libs.NNGrid.Utils;
using Managistics.Warehouse.Views.Libs.NNGrid.Columns;
using Managistics.Utility.Views.NNGrid.Datas;
using System.Drawing;
using System.Windows.Forms;  //test

namespace Managistics.Warehouse.Views.Libs.NNGrid
{
    public class NNGridEditor<T> : ObjectListView where T : class
    {
        //Data source for grid
        private List<T> dataSource;
        //A flag check for editing or not
        private bool isEdit;
        //
        private List<NNGridColumn> listColumns = new List<NNGridColumn>();
       
        //===========================================================================================
        // Constructure
        //===========================================================================================
        public NNGridEditor()
        {            
            loadDefaultValues();           
        }

        //===========================================================================================
        // Set default values
        //===========================================================================================
        private void loadDefaultValues()
        {
            this.FullRowSelect = NNGridViewConstants.FULL_ROW_SELECT;
            this.Location = new Point(NNGridViewConstants.LOCATION_X, NNGridViewConstants.LOCATION_Y);
            this.Name = NNGridViewConstants.NAME;
            this.ShowGroups = NNGridViewConstants.SHOW_GROUPS;
            this.Size = new Size(NNGridViewConstants.SIZE_X, NNGridViewConstants.SIZE_Y);
            this.TabIndex = NNGridViewConstants.TAB_INDEX;
            this.CellEditTabChangesRows = NNGridViewConstants.CELL_EDIT_TAB_CHANGES_ROWS;
            this.CellEditActivation = NNGridViewConstants.CELL_EDIT_ACTIVATION;
            this.UseAlternatingBackColors = NNGridViewConstants.USE_ALTERNATING_BACK_COLORS;
            this.UseCompatibleStateImageBehavior = NNGridViewConstants.USE_COMPATIBLE_STATE_IMAGE_BEHAVIOR;
        }

        //===========================================================================================
        // Getter/Setter
        //===========================================================================================
               
        public List<T> DataSource
        {
            get { return dataSource; }
            set { dataSource = value; }
        }             
        
        public bool IsEdit
        {
            get { return isEdit; }
            set { isEdit = value; }
        }
                
        public List<NNGridColumn> ListColumns
        {
            get { return listColumns; }
            set { listColumns = value; }
        }
                        
        //===========================================================================================
        // Business functions
        //===========================================================================================

        /**
         * Initialize
         * 
         */
        public void Initialize()
        {
            if (this == null)
                return;
            ((System.ComponentModel.ISupportInitialize)(this)).BeginInit();
            //
            this.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
                | System.Windows.Forms.AnchorStyles.Left)
                | System.Windows.Forms.AnchorStyles.Right)));
                      
            this.View = System.Windows.Forms.View.Details;
                       
            //Add columns
            System.Windows.Forms.ColumnHeader[] columnHeaders = new System.Windows.Forms.ColumnHeader[ListColumns.Count()];
            int i = 0;
            foreach (NNGridColumn cl in ListColumns)
            {
                this.AllColumns.Add(cl);
                columnHeaders[i] = cl;
                i++;
            }
            this.Columns.AddRange(columnHeaders);
            //
            this.CellEditStarting += this.olv_ToCellEditStarting;
            this.CellEditFinishing += this.olv_ToCellEditFinishing;            
            
            this.SuspendLayout();
            ((System.ComponentModel.ISupportInitialize)(this)).EndInit();
        }


        private void olv_ToCellEditStarting(object sender, CellEditEventArgs e)
        {           
            //
            NNGridColumn col = (NNGridColumn)e.Column;

            if (col.CellEditStarting != null)
            {               
                col.CellEditStarting(sender, e);
            }
            else
            {                
                // Get the constructor and create an instance of Class
                Type magicType = Type.GetType("Managistics.Warehouse.Views.Libs.NNGrid.Controls." + NNUtils.GetEnumDescription((col).ControlType));
                if (magicType != null)
                {
                    ConstructorInfo magicConstructor = magicType.GetConstructor(new[] { typeof(object), typeof(CellEditEventArgs) });
                    object magicClassObject = magicConstructor.Invoke(new object[] { sender, e });

                    MethodInfo magicMethod = magicType.GetMethod("Initialize");
                    if (magicMethod != null)
                        magicMethod.Invoke(magicClassObject, new object[] { });

                    Control myCtr = (Control)magicClassObject;
                    myCtr.Bounds = e.CellBounds;
                    myCtr.Font = ((ObjectListView)sender).Font;
                    e.Control = myCtr;
                }
                                
            }

        }

        private void olv_ToCellEditFinishing(object sender, CellEditEventArgs e)
        {
            //
            NNGridColumn col = (NNGridColumn)e.Column;            
            if (col.CellEditFinishing != null)
            {
                col.CellEditFinishing(sender, e);
            }
            else
            {               
                //
                Type toObjectType = e.RowObject.GetType();
                System.Reflection.PropertyInfo toProperty = toObjectType.GetProperty(e.Column.AspectName);

                //string value = ((ComboBox)e.Control).SelectedItem.ToString();
                Type magicType = Type.GetType("Managistics.Warehouse.Views.Libs.NNGrid.Controls." + NNUtils.GetEnumDescription((col).ControlType));
                if (magicType != null)
                {
                    ConstructorInfo magicConstructor = magicType.GetConstructor(new[] { typeof(object), typeof(CellEditEventArgs) });
                    object magicClassObject = magicConstructor.Invoke(new object[] { sender, e });

                    MethodInfo magicMethod = magicType.GetMethod("DataResponse");
                    if (magicMethod != null)
                    {
                        string[] words = e.Column.AspectName.Split('.');
                        string aspectObjName = words.Length > 0 ? words[0] : e.Column.AspectName;
                        System.Reflection.PropertyInfo toProperty2 = toObjectType.GetProperty(aspectObjName);
                        object val = magicMethod.Invoke(magicClassObject, new object[] { });
                        toProperty2.SetValue(e.RowObject, val, null);
                    }

                }

                // Any updating will have been down in the SelectedIndexChanged event handler
                // Here we simply make the list redraw the involved ListViewItem
                ((ObjectListView)sender).RefreshItem(e.ListViewItem);

                // We have updated the model object, so we cancel the auto update
                e.Cancel = true;                
            }
                        
        }
    }
}
